﻿//========================================================= 
/**@file MouseMirror.h
 * @brief 模拟鼠标操作
 * 
 * @date 2018-08-27   14:54:56
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_MOUSEMIRROR_H_
#define _LIBZHOUYB_MOUSEMIRROR_H_
//--------------------------------------------------------- 
#include "../../../include/Base.h"
//--------------------------------------------------------- 
namespace zhou_yb {
namespace extension {
namespace ability {
//--------------------------------------------------------- 
/**
 * @brief 模拟鼠标按键
 * @date 2018-08-27 14:04
 */
class MouseMirror
{
public:
    static inline void Event(DWORD e, DWORD x, DWORD y, DWORD wheel = 0)
    {
        static double dX = static_cast<double>(65535 / GetSystemMetrics(SM_CXSCREEN));
        static double dY = static_cast<double>(65535 / GetSystemMetrics(SM_CYSCREEN));
        mouse_event(e, static_cast<DWORD>(x * dX), static_cast<DWORD>(y * dY), wheel, GetMessageExtraInfo());
    }
    static inline void Position(DWORD& x, DWORD& y)
    {
        POINT p;
        GetCursorPos(&p);

        x = p.x;
        y = p.y;
    }
    static inline void Position(POINT& p)
    {
        GetCursorPos(&p);
    }
    static inline void To(DWORD x, DWORD y)
    {
        SetCursorPos(x, y);
    }
    static inline void To(const POINT& p)
    {
        SetCursorPos(p.x, p.y);
    }
    static inline void LeftClick(DWORD x, DWORD y)
    {
        Event(MOUSEEVENTF_LEFTDOWN, x, y);
        Event(MOUSEEVENTF_LEFTUP, x, y);
    }
    static inline void RightClick(DWORD x, DWORD y)
    {
        Event(MOUSEEVENTF_RIGHTDOWN, x, y);
        Event(MOUSEEVENTF_RIGHTUP, x, y);
    }
    static inline void Move(DWORD x, DWORD y)
    {
        Event(MOUSEEVENTF_MOVE, x, y);
    }
    static void Drag(DWORD x, DWORD y, uint speedMs = 0, uint minIntervalMs = DEV_OPERATOR_INTERVAL)
    {
        POINT p;
        GetCursorPos(&p);

        Event(MOUSEEVENTF_LEFTDOWN, p.x, p.y);
        size_t count = speedMs / minIntervalMs;
        int offsetX = (x - p.x) / count;
        int offsetY = (y - p.y) / count;
        for(size_t i = 0; i < count; ++i)
        {
            Move(p.x + i * offsetX, p.y + i * offsetY);
            Timer::Wait(minIntervalMs);
        }
        Move(x, y);
        Event(MOUSEEVENTF_LEFTUP, x, y);
    }
};
//--------------------------------------------------------- 
/**
 * @brief 鼠标动作接口
 * @date 2018-11-04 10:29:45
 */
struct IMouseAction
{
    virtual void OnAction(DWORD x, DWORD y, size_t wheel) = 0;

    virtual ~IMouseAction() {}
};
/**
 * @brief 鼠标钩子事件处理器接口
 * @date 2018-08-30 08:59
 */
struct IMouseHookHandler
{
    virtual bool HookProc() = 0;

    virtual ~IMouseHookHandler() {}
};
/**
 * @brief 鼠标钩子
 *
 * 统一劫持后根据注册的对象处理事件进行分发,Reactor模式
 * 
 * @date 2018-08-30 08:58
 */
class MouseHook
{
protected:
    HHOOK _hMouseHook;

    static LRESULT CALLBACK MouseHookProc(UINT nCode, WPARAM wParam, LPARAM lParam)
    {
        return TRUE;
    }
public:
    bool Install()
    {
        return true;
    }
};
/**
 * @brief 鼠标操作捕获
 * @date 2018-08-30 08:58
 */
class MouseCapture
{

};
/**
 * @brief 鼠标动画
 * @date 2018-08-27 14:53
 */
class MouseAnimation
{
protected:
    list_t<IMouseAction*> _frames;
};
//--------------------------------------------------------- 
} // namespace ability 
} // namespace extension 
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_MOUSEMIRROR_H_
//========================================================= 
